<?php


namespace app\openwx\controller;

use app\common\library\wechat\WxBizMsgCrypt;
use think\Db;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Log;
use think\facade\Request;
use think\helper\Time;


class Openweixin extends Base
{

    public function msg()
    {
        //dump(input('appid'));
        if (input('?appid')) {
            Log::write(file_get_contents('php://input'), 'WXMSG1');
            $config['token'] = config('param.openwx_token');
            $config['encodingAesKey'] = config('param.encodingAesKey');
            $config['appId'] = config('param.component_appid');
            // dump($config);
            //获取第三方配置信息
            // 接收公众号平台发送的消息
            $timeStamp = input('timestamp');
            $nonce = input('nonce');
            $msg_sign = input('msg_signature');
            $encryptMsg = file_get_contents('php://input');
            //创建解密类
            Log::write(input('param.'), 'WXMSG2');
            // dump(cache('ComponentVerifyTicket'));
            if (input('?timestamp')) {
            } else {
                return 'success';

            }

            libxml_disable_entity_loader(true);
            $xml_obj = (array)simplexml_load_string($encryptMsg, 'SimpleXMLElement', LIBXML_NOCDATA);
            // 重新拼接xml
            $encrypt = $xml_obj['Encrypt'];
            $encryptMsg = sprintf("<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>", $encrypt);

            // 解密
            $pc = new WXBizMsgCrypt($config['token'], $config['encodingAesKey'], $config['appId']);
            $msg = '';
            $errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $encryptMsg, $msg);
            //dump($errCode);
            if ($errCode) {
                Log::write('微信消息错误' . $errCode, 'WX_ERROR');
            } else {
                libxml_disable_entity_loader(false);
                $xml_string = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA);
                $msg = json_decode(json_encode($xml_string), true);
//                //第三方平台全网发布检测普通文本消息测试
//                if (strtolower($msg['MsgType']) == 'text' && $msg['content'] == 'TESTCOMPONENT_MSG_TYPE_TEXT') {
//                    $toUsername = trim($msg['ToUserName']);
//                    if ($toUsername == 'gh_3c884a361561') {
//                        $content = 'TESTCOMPONENT_MSG_TYPE_TEXT_callback';
//                        echo $this->responseText($msg, $content);
//                    }
//                }
//                //第三方平台全网发布检测返回api文本消息测试
//                if (strpos($msg['content'], 'QUERY_AUTH_CODE') !== false) {
//                    $toUsername = trim($msg['ToUserName']);
//                    if ($toUsername == 'gh_3c884a361561') {
//                        $query_auth_code = str_replace('QUERY_AUTH_CODE:', '', $msg['content']);
//                        $params = $this->dedeLogic->api_query_auth($query_auth_code);
//                        $authorizer_access_token = $params['authorization_info']['authorizer_access_token'];
//                        $content = "{$query_auth_code}_from_api";
//                        $this->sendServiceText($msg, $content, $authorizer_access_token);
//                    }
//                }
                //dump($msg);
                Log::write(json_encode($msg), 'WXMSG3');
                // 数据处理分流
                \think\facade\Log::write(json_encode($xml_string), 'xml');
                $id = DB::name('product_wx')->where('authorizer_appid', input('param.appid'))->value('product_run_id');
                $this->shunt($msg, $id);
                //终止执行
                // exit;
            }
        } else {
            $this->assign('info', '参数错误-10000');
            return view('work/error');
        }
    }


    private function shunt($data, $id)
    {
        switch ($data['MsgType']) {
            case 'text': //文本
                $this->text_msg($data, $id);
                break;
            case 'image': //图像
                break;
            case 'voice': //语音
                // $this->voice_msg($data);
                break;
            case 'video': //视频
                break;
            case 'location': //地理位置
                $this->location($data, $id);
                break;
            case 'link': //链接
                break;
            case 'event': //事件
                //事件二次分流
                switch ($data['Event']) {
                    case 'subscribe': //订阅
                         $this->subscribe($data);
                        break;
                    case 'unsubscribe': //取消订阅
                        break;
                    case 'SCAN': //二维码扫描
                        $this->subscribe($data);
                        break;
                    case 'LOCATION': //上报地理位置
                        $this->location($data, $id);
                        break;
                    case 'CLICK': //菜单
                        break;
                    case 'VIEW': //菜单跳转url
                        break;
                    case 'scancode_waitmsg': //扫码
                        break;
                    case 'TEMPLATESENDJOBFINISH': //模板消息发送结束
                        $this->tmp_status($data, $id);
                        break;
                    default:
                        echo "10004"; //新增加的事件
                }
                break;
            default:
                echo "10005"; //新增加的类型
        }
    }
    public function subscribe($data = '', $id = 0)
    {
        \think\facade\Log::write(json_encode($data), 'WX_TEXT1');
        $timeStamp = time();
        $res = "<xml><ToUserName>" . $data['FromUserName'] . "</ToUserName><FromUserName>" . $data['ToUserName'] . "</FromUserName><CreateTime>" . $timeStamp . "</CreateTime><MsgType>text</MsgType><Content>" . '谢谢您关注公众号' . "</Content></xml>";
        // Log::write('微信消息' . $res, 'WX_TEXT2');
        $config['token'] = config('param.openwx_token');
        $config['encodingAesKey'] = config('param.encodingAesKey');
        $config['appId'] = config('param.component_appid');
        $pc = new WXBizMsgCrypt($config['token'], $config['encodingAesKey'], $config['appId']);
        $nonce = md5(time());
        $encryptMsg = ''; //加密后的密文
        $errCode = $pc->encryptMsg($res, $timeStamp, $nonce, $encryptMsg);
        //dump($errCode);
        if ($errCode) {
            Log::write('微信消息错误' . $errCode, 'WX_TEXT3');
        } else {
            Log::write('微信消息' . $encryptMsg, 'WX_TEXT4');
            echo $encryptMsg;
        }
    }
    public function text_msg($data = '', $id = 0)
    {
        \think\facade\Log::write(json_encode($data), 'WX_TEXT1');
        $timeStamp = time();
        $res = "<xml><ToUserName>" . $data['FromUserName'] . "</ToUserName><FromUserName>" . $data['ToUserName'] . "</FromUserName><CreateTime>" . $timeStamp . "</CreateTime><MsgType>text</MsgType><Content>" . '客服消息暂时没有开通' . "</Content></xml>";
        // Log::write('微信消息' . $res, 'WX_TEXT2');
        $config['token'] = config('param.openwx_token');
        $config['encodingAesKey'] = config('param.encodingAesKey');
        $config['appId'] = config('param.component_appid');
        $pc = new WXBizMsgCrypt($config['token'], $config['encodingAesKey'], $config['appId']);
        $nonce = md5(time());
        $encryptMsg = ''; //加密后的密文
        $errCode = $pc->encryptMsg($res, $timeStamp, $nonce, $encryptMsg);
        //dump($errCode);
        if ($errCode) {
            Log::write('微信消息错误' . $errCode, 'WX_TEXT3');
        } else {
            Log::write('微信消息' . $encryptMsg, 'WX_TEXT4');
            echo $encryptMsg;
        }
    }

    public function location($data = '', $id = 0)
    {
        if (empty($data)) {
            return '404';
        }
        \think\facade\Log::write(json_encode($data), 'WX_LOCTION');
        $uid = DB::connect($this->dbconfig($id))->name('admin')->where('openid', $data['FromUserName'])->cache(600)->value('id');
        if (cache('location_u' . $uid)) {
            return '200';
        }
        cache('location_u' . $uid, 600);
        $data2 = [];
        $data = $this->get_coder($data);
        //dump($data);
        $data2['uid'] = $uid;
        $data2['c_time'] = time();
        $data2['location'] = $data['location'];
        $data2['status'] = $data['distance'] ? 1 : 2;
        DB::connect($this->dbconfig($id))->name('workreg')->insert($data2);
        \think\facade\Log::write($uid, 'WX_LOCTION_1');
        // if ($uid == 33) {
        //$data=[];
        //$data['ToUserName'] = 'oG6HnwS9q-f8Fxf5F8AFL-xD98vU';
        // $data['FromUserName']='gh_a0cd571dcd92';
        $timeStamp = time();
        $res = "<xml><ToUserName>" . $data['FromUserName'] . "</ToUserName><FromUserName>" . $data['ToUserName'] . "</FromUserName><CreateTime>" . $timeStamp . "</CreateTime><MsgType>text</MsgType><Content>" . '当前位置在' . $data['location'] . "</Content></xml>";
        //Log::write('微信消息' . $res, 'WX_ERROR_location3');
        $config['token'] = config('param.openwx_token');
        $config['encodingAesKey'] = config('param.encodingAesKey');
        $config['appId'] = config('param.component_appid');
        $pc = new WXBizMsgCrypt($config['token'], $config['encodingAesKey'], $config['appId']);
        $nonce = md5(time());
        $encryptMsg = ''; //加密后的密文
        $errCode = $pc->encryptMsg($res, $timeStamp, $nonce, $encryptMsg);
        if ($errCode) {
            Log::write('微信消息错误' . $errCode, 'WX_ERROR_location');
        } else {
            //Log::write('微信消息' . $encryptMsg, 'WX_ERROR_location2');
            echo $encryptMsg;
        }
        //dump($encryptMsg);
        //}
    }

    public function get_coder($data = '')
    {
//        $data=[];
//        $data['Latitude']='39.631977';
//        $data['Longitude']='118.153671';
        // \think\facade\Log::write(json_encode($data), 'get_coder_data');
        $url = 'https://apis.map.qq.com/ws/geocoder/v1/?location=';
        $url .= $data['Latitude'] . ',' . $data['Longitude'];
        $url .= '&key=' . config('param.tengmapkey');
        // dump(config('param.tengmapkey'));
        $res = file_get_contents($url);
        // \think\facade\Log::write($res, 'get_coder_data');
        $res = json_decode($res, true);
        //dump($res);
        if ($res['status'] == 0) {
            $data['location'] = $res['result']['formatted_addresses']['recommend'];
        } else {
            // \think\facade\Log::write($res, 'GET_CODER');
            $data['location'] = '未知地域';
        }
        //  \think\facade\Log::write($url, 'get_coder_url');
        $location = config('param.c_location');
        $url = 'https://apis.map.qq.com/ws/distance/v1/?parameters';
        $url .= '&mode=walking&from=' . $location[1] . ',' . $location[2];
        $url .= '&to=' . $data['Latitude'] . ',' . $data['Longitude'];
        $url .= '&key=' . config('param.tengmapkey');
        $res = file_get_contents($url);
        // \think\facade\Log::write($res, 'get_coder_data');
        $res = json_decode($res, true);
        // dump($res);
        if ($res['status'] == 0) {
            if ($res['result']['elements'][0]['distance'] < $location[3]) {
                $data['distance'] = true;
            } else {
                $data['distance'] = false;
            }
            // dump($location[3]);
        } else {
            //\think\facade\Log::write($res, 'GET_CODER');
            $data['distance'] = false;
        }
        return $data;
    }

    function dbconfig($id)
    {
        return [
            'type' => 'mysql',
            // 服务器地址
            'hostname' => 'rm-2zea426o72962o97z125010.mysql.rds.aliyuncs.com',
            // 数据库名
            'database' => 'u' . $id,
            // 用户名
            'username' => 'weibuyun',
            // 密码
            'password' => 'Wei@#$1209C!=',
        ];
    }

    public function tmp_status($data, $id)
    {
        switch ($data['Status']) {
            case 'success':
                $status = 3;
                break;
            case 'failed:user block':
                $status = 4;
                break;
            case 'failed: system failed':
                $status = 5;
                break;
            default:
                $status = 6;
        }
        DB::connect($this->dbconfig($id))->name('wx_msg_info')->where('msgid', $data['MsgID'])->update(['status' => $status]);
    }

    /**
     * 异步通知处理
     */
    public function auth()
    {
        $config['token'] = config('param.openwx_token');
        $config['encodingAesKey'] = config('param.encodingAesKey');
        $config['appId'] = config('param.component_appid');
        //获取第三方配置信息
        // 接收公众号平台发送的消息
        $timeStamp = input('timestamp');
        $nonce = input('nonce');
        $msg_sign = input('msg_signature');
        $encryptMsg = file_get_contents('php://input');
        //创建解密类
        Log::write(input('param.'), 'WX_ERROR');
        // dump(cache('ComponentVerifyTicket'));
        if (input('?timestamp')) {

        } else {
            return 'success';

        }
        //        $timeStamp = '1585191201';
        //        $nonce = '1254950728';
        //        $msg_sign = '5e53fbee9b89210c84a3f9b2e94d296c7c5ac492';
        //        $encryptMsg = file_get_contents('php://input');
        //
        //        $encryptMsg = '<xml>
        //    <AppId><![CDATA[wxb798c8598fb0773f]]></AppId>
        //    <Encrypt><![CDATA[6BXxks46xWxcx0iBTT/d4urCHbughXBWLHWfVjMI4X0hUqeT510hBSZomU4IXxeSIlLRDOZ0vX3DchKqcmeFMyLMivp0GMU0lZc6afHcUuq1jvgR+K2APpoiQ64Gip1WBTLndMzu9u+40qcHz1kMx6xLtzuHdayhc1aR4nYPuMBGRs235q727ZlLp/MTwJr5Mt3zpB4Ljnr0S9f/l93RGzO/0r1TSxPVtZRdrOk3qp21EwBTd+W/8aaTUplsAFYEJRUDL5fG8UHcnD4KqJsZzQjp6YfCYpflFc4YN7AwGixDqRFEzmN9yMySoWVUihkGMSgm3+DvjqfHGHwxu6btDLeWI/3RPNxpEgJIErv6Tgd3m+LQ3W+wAlu4h3lFxFDTJQf2wQ6DYBnpgANj16tZFD5O2XgK9sW2/Q6tScCDdrX+5gvf9173PG5iuW1SW8Gw2QqAEfn5juUo4R57cWDRnQ==]]></Encrypt>
        //</xml>';
        libxml_disable_entity_loader(true);
        $xml_obj = (array)simplexml_load_string($encryptMsg, 'SimpleXMLElement', LIBXML_NOCDATA);
        // 重新拼接xml
        $encrypt = $xml_obj['Encrypt'];
        $encryptMsg = sprintf("<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>", $encrypt);

        // 解密
        $pc = new WXBizMsgCrypt($config['token'], $config['encodingAesKey'], $config['appId']);
        $msg = '';
        $errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $encryptMsg, $msg);

        if ($errCode) {
            Log::write('微信消息错误' . $errCode, 'WX_ERROR');
        } else {
            libxml_disable_entity_loader(false);
            $xml_string = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA);
            $msg = json_decode(json_encode($xml_string), true);
            //dump($msg);
            //缓存


            if (isset($msg['ComponentVerifyTicket'])) {
                cache('ComponentVerifyTicket', $msg['ComponentVerifyTicket']);
                //微信第三方平台api_component_token
                $this->get_token();
            }
            //授权成功
            if (isset($msg['InfoType'])) {

                if ($msg['InfoType'] == 'unauthorized') {
                    DB::name('product_wx')->where('authorizer_appid', $msg['AuthorizerAppid'])->delete();
                }
                if ($msg['InfoType'] == 'unauthorized') {
                    DB::name('product_wx')->where('authorizer_appid', $msg['AuthorizerAppid'])->delete();
                }
            }

        }
        Log::write('微信消息' . json_encode($msg), 'WX_INFO');
//        //存库
//        DB::name('config')->where('id', 110)->update(['value' => $msg['ComponentVerifyTicket'], 'update_time' => time()]);
        return 'success';

    }



    function get_token()
    {
        $appid = config('param.component_appid');
        $appsecret = config('param.component_appsecret');
        $ticket = cache('ComponentVerifyTicket');
        //dump(config());
        if (cache('ComponentVerifyTicket')) {
            $url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
            $data = '{"component_appid":"' . $appid . '","component_appsecret":"' . $appsecret . '","component_verify_ticket":"' . $ticket . '"}';
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            $tmpInfo = curl_exec($ch);
            $re = json_decode($tmpInfo, TRUE);

            if ($re['component_access_token']) {
                cache('component_access_token', $re['component_access_token']);
                DB::name('config')->where('id', 112)->update(['value' => $re['component_access_token'], 'update_time' => time()]);
            } else {
                //错误，做处理
                Log::write(json_encode($re), 'WX_TOKEN_ERROR');
            }
        }

    }
}